﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using EzPos.GUIs.Forms;
using EzPos.Model.Common;
using EzPos.Model.SaleOrder;
using EzPos.Model.Table;
using EzPos.Properties;
using EzPos.Service;
using EzPos.Service.Common;
using EzPos.Service.SaleOrder;
using EzPos.Service.Table;

namespace EzPos.GUIs.Controls
{
    public partial class CtrlSaleResto : UserControl
    {
        private CommonService _commonService;
        private IList _tableList;
        private TableService _tableService;
        private SaleOrderService _saleOrderService;
        private bool _allowToMove;

        public CtrlSaleResto()
        {
            InitializeComponent();
        }

        public SaleOrderService SaleOrderService
        {
            set { _saleOrderService = value; }
        }

        private void CtrlSale_Load(object sender, EventArgs e)
        {
            try
            {
                if (_commonService == null)
                    _commonService = ServiceFactory.GenerateServiceInstance().GenerateCommonService();
                if (_saleOrderService == null)
                    _saleOrderService = ServiceFactory.GenerateServiceInstance().GenerateSaleOrderService();
                if (_tableService == null)
                    _tableService = ServiceFactory.GenerateServiceInstance().GenerateTableService();

                //Retrieve and Draw table
                InitializeTable();

                //Allow to move table
                _allowToMove = true;
            }
            catch (Exception exception)
            {
                FrmExtendedMessageBox.UnknownErrorMessage(
                    Resources.MsgCaptionUnknownError,
                    exception.Message);
            }
        }

        private void InitializeTable()
        {
            if(tlpTable == null)
                return;

            _tableList = _tableService.GetTables();
            var rowCounter = 0;
            var columnCounter = 0;
            foreach (Table table in _tableList)
            {
                var btnTable = 
                    new Button
                    {
                        Text = table.TableName,
                        FlatStyle = FlatStyle.Popup,
                        Size = new Size(200, 80),
                        BackgroundImageLayout = ImageLayout.Stretch,
                        UseVisualStyleBackColor = false,
                        Font = new Font("Candara", 14F, FontStyle.Bold, GraphicsUnit.Point, 0),
                        Anchor = AnchorStyles.None
                    };

                btnTable.MouseEnter += BtnMouseEnterHandler;
                btnTable.MouseDown += BtnMouseDownHandler;
                btnTable.DragEnter += BtnDragEnterHandler;
                btnTable.DragDrop += BtnDragDropHandler;            

                btnTable.AllowDrop = true;

                if (table.SaleOrderId != 0)
                    btnTable.BackgroundImage = Resources.background_9;

                tlpTable.Controls.Add(btnTable, columnCounter, rowCounter);                                
                
                columnCounter += 1;
                if (columnCounter != 5) 
                    continue;

                rowCounter += 1;
                columnCounter = 0;

                //tlpTable.RowCount += 1;
                //var rowStyle = new RowStyle { Height = 100, SizeType = SizeType.Absolute };
                //tlpTable.RowStyles.Add(rowStyle);
            }

            //tlpTable.Refresh();
        }

        private void TableRelocationHandler(string fromTableName, string toTableName)
        {
            try
            {
                var briefMsg = "អំពីការ​លក់";
                var detailMsg = Resources.MsgRelocateTable;
                using (var frmMessageBox = new FrmExtendedMessageBox())
                {
                    frmMessageBox.BriefMsgStr = briefMsg;
                    frmMessageBox.DetailMsgStr = detailMsg;
                    if (frmMessageBox.ShowDialog(this) != DialogResult.OK)
                        return;
                }

                detailMsg = _tableService.TableRelocationHandler(_tableList, fromTableName, toTableName);
                if (!string.IsNullOrEmpty(detailMsg))
                {
                    briefMsg = "អំពីការ​ផ្លាស់ប្ដូរ​តុ";
                    using (var frmMessageBox = new FrmExtendedMessageBox())
                    {
                        frmMessageBox.BriefMsgStr = briefMsg;
                        frmMessageBox.DetailMsgStr = detailMsg;
                        frmMessageBox.IsCanceledOnly = true;
                        frmMessageBox.ShowDialog(this);
                        return;
                    }
                }

                //Repaint table
                foreach (var btnTable in
                    tlpTable.Controls.Cast<object>().
                    Where(control => control.GetType().Equals(typeof(Button))).OfType<Button>())
                {
                    if (btnTable.Text.Equals(fromTableName))
                        btnTable.BackgroundImage = null;
                    else if (btnTable.Text.Equals(toTableName))
                        btnTable.BackgroundImage = Resources.background_9;
                }
            }
            catch (Exception exception)
            {
                FrmExtendedMessageBox.UnknownErrorMessage(
                    Resources.MsgCaptionUnknownError, exception.Message);
            }
        }

        private void BtnDragDropHandler(object sender, DragEventArgs e)
        {
            if (!_allowToMove)
                return;

            //To
            if(sender == null)
                return;

            if (sender.GetType() != typeof(Button))
                return;

            var btnTable = sender as Button;
            if (btnTable == null)
                return;
            var toTableName = btnTable.Text;

            //From
            if(e == null)
                return;
            var fromTableName = e.Data.GetData(DataFormats.StringFormat).ToString();

            if (fromTableName.Equals(toTableName))
                return;

            TableRelocationHandler(fromTableName, toTableName);
        }

        private static void BtnDragEnterHandler(object sender, DragEventArgs e)
        {
            e.Effect = 
                e.Data.GetDataPresent(DataFormats.StringFormat) ? 
                DragDropEffects.Copy : 
                DragDropEffects.None;
        }

        private void BtnMouseDownHandler(object sender, MouseEventArgs e)
        {
            if (sender == null)
                return;

            if (sender.GetType() != typeof(Button))
                return;

            var btnTable = sender as Button;
            if (btnTable == null)
                return;
         
            if ((e.Button == MouseButtons.Left) && (e.Clicks == 2))
            {
                SaleHandler(btnTable);
            }

            SetTableInfo(btnTable);

            btnTable.DoDragDrop(btnTable.Text, DragDropEffects.Copy | DragDropEffects.Move);
        }

        private void SetTableInfo(Control btnTable)
        {
            if (btnTable == null)
                return;

            var table = _tableService.RetrieveTable(_tableList, btnTable.Text);
            if (table == null)
                return;

            //Customer info
            lblCustomer.Text = table.TableName;

            //Invoice info
            SetInvoiceInfo(table);
        }

        private void SetInvoiceInfo(Table table)
        {
            try
            {
                var searchCriteria = new List<string> { "SaleOrderId|" + table.SaleOrderId };
                var saleOrderList = _saleOrderService.GetSaleOrders(searchCriteria);
                if ((saleOrderList == null) || (saleOrderList.Count == 0))
                {
                    ResetInvoiceInfo();
                    return;
                }

                var saleOrder = saleOrderList[0] as SaleOrder;
                if (saleOrder == null)
                {
                    ResetInvoiceInfo();
                    return;
                }

                var exchangeRate = AppContext.ExchangeRate.ExchangeValue;
                var saleItemList = _saleOrderService.GetSaleItems(saleOrder.SaleOrderId);
                var totalAmountLocal = (from SaleItem saleItem in saleItemList where saleItem != null select saleItem.UnitPriceOut * saleItem.QtySold).Sum();

                lblInvoiceNum.Text = saleOrder.SaleOrderNumber;
                lblSubTotalAmountLocal.Text =
                    string.Format("{0} {1}", Resources.ConstCurrencyRiel, totalAmountLocal.ToString("N", AppContext.CultureInfo));

                var totalAmountForeign = totalAmountLocal / exchangeRate;
                lblSubTotalAmountForeign.Text =
                    string.Format("{0} {1}", Resources.ConstCurrencyDollar, totalAmountForeign.ToString("N", AppContext.CultureInfo));

                lblDiscountPercentage.Text = 
                    string.Format("{0}{1}", saleOrder.Discount.ToString("N0", AppContext.CultureInfo), "%");

                var discountAmountForeign = (totalAmountForeign*saleOrder.Discount)/100;
                var discountAmountLocal = (totalAmountLocal*saleOrder.Discount)/100;

                lblDiscountAmountForeign.Text =
                    string.Format("{0} {1}", Resources.ConstCurrencyDollar, discountAmountForeign.ToString("N", AppContext.CultureInfo));
                lblDiscountAmountLocal.Text =
                    string.Format("{0} {1}", Resources.ConstCurrencyRiel, discountAmountLocal.ToString("N", AppContext.CultureInfo));

                var toPayAmountForeign = totalAmountForeign - discountAmountForeign;
                var toPayAmountLocal = totalAmountLocal - discountAmountLocal;

                lblTotalAmountForeign.Text =
                    string.Format("{0} {1}", Resources.ConstCurrencyDollar, toPayAmountForeign.ToString("N", AppContext.CultureInfo));
                lblTotalAmountLocal.Text =
                    string.Format("{0} {1}", Resources.ConstCurrencyRiel, toPayAmountLocal.ToString("N", AppContext.CultureInfo));
            }
            catch (Exception exception)
            {
                FrmExtendedMessageBox.UnknownErrorMessage(
                    Resources.MsgCaptionUnknownError, exception.Message);
            }
        }

        private void ResetInvoiceInfo()
        {
            lblInvoiceNum.Text = string.Empty;
            lblSubTotalAmountForeign.Text = string.Format("{0} {1}", Resources.ConstCurrencyDollar, Resources.ConstAmountZero);
            lblSubTotalAmountLocal.Text = string.Format("{0} {1}", Resources.ConstCurrencyRiel, Resources.ConstAmountZero);

            lblDiscountPercentage.Text = string.Empty;
            lblDiscountAmountForeign.Text = string.Format("{0} {1}", Resources.ConstCurrencyDollar, Resources.ConstAmountZero);
            lblDiscountAmountLocal.Text = string.Format("{0} {1}", Resources.ConstCurrencyRiel, Resources.ConstAmountZero);

            lblTotalAmountForeign.Text = string.Format("{0} {1}", Resources.ConstCurrencyDollar, Resources.ConstAmountZero);
            lblTotalAmountLocal.Text = string.Format("{0} {1}", Resources.ConstCurrencyRiel, Resources.ConstAmountZero);
        }

        private void SaleHandler(Control btnTable)
        {
            if (btnTable == null)
                return;

            var table = _tableService.RetrieveTable(_tableList, btnTable.Text);
            if(table == null)
                return;

            Visible = false;
            using (var frmSale = new FrmSale())
            {
                _allowToMove = false;
                frmSale.Table = table;
                frmSale.WindowState = FormWindowState.Maximized;
                if(frmSale.ShowDialog(this) == DialogResult.OK)
                {
                    btnTable.BackgroundImage =
                        frmSale.Table.SaleOrderId != 0 ?
                        Resources.background_9 :
                        null; 
                }
                Visible = true;
            }
        }

        private void BtnMouseEnterHandler(object sender, EventArgs e)
        {
            _allowToMove = true;
        }

        private void BtnSearchClick(object sender, EventArgs e)
        {
            try
            {
                Visible = false;
                using (var frmSaleSearch = new FrmSaleSearch())
                {
                    frmSaleSearch.ShowDialog(this);
                    Visible = true;
                }                
            }
            catch (Exception exception)
            {
                FrmExtendedMessageBox.UnknownErrorMessage(
                    Resources.MsgCaptionUnknownError,
                    exception.Message);
            }   
        }
    }
}